#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gnome.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"

#include "image/math_morph/math_morph.h"
#include "utils/runMorphOp.h"

#define IMAGE_EXTENSION "bmp"

GtkFileFilter *filter= NULL;

GtkWidget *fileChooserDialog= NULL;

GtkWidget *_2CannApp, *selectSourcePathDialog, *fileChooserDialog;

gboolean imageIsSelected = FALSE;

Image *imageSelected= NULL;

char imageFilename[512];
char *selectSourcePath;

EEType eeType = EE_NULL;
char *mathMorphOP = NULL;

gboolean on_2cann_app_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
	gtk_main_quit();
	return FALSE;
}

void on_new1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_open1_activate(GtkMenuItem *menuitem, gpointer user_data) {
	if (fileChooserDialog == NULL) {
		fileChooserDialog = create_fileChooserDialog();
	}
	gtk_widget_show(fileChooserDialog);
}

void on_save1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_save_as1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_quit1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_cut1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_copy1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_paste1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_clear1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_properties1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_preferences1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_about1_activate(GtkMenuItem *menuitem, gpointer user_data) {

}

void on_toolbutton2_clicked(GtkToolButton *toolbutton, gpointer user_data) {
	GdkPixbuf *gdkPixbuf;
	char *extension;
	
	extension = (char*)malloc(sizeof("*.") + sizeof(IMAGE_EXTENSION));
	sprintf(extension, "*.%s", IMAGE_EXTENSION);
	fileChooserDialog = gtk_file_chooser_dialog_new ("Open File", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);

	filter = gtk_file_filter_new();
	gtk_file_filter_set_name (filter, "pixmap");
	gtk_file_filter_add_pattern (filter, extension);
	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooserDialog), filter);

	if (gtk_dialog_run (GTK_DIALOG (fileChooserDialog))	== GTK_RESPONSE_ACCEPT) {

		char* filename = (char*)malloc(512 * sizeof(char));
		int width, height, rowstride, n_channels, i, j;
		guchar *pixels, *p;
		Image* image;
		pixel **Matrix;

		filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooserDialog));

		gtk_label_set_text(GTK_LABEL(lookup_widget(_2CannApp, "_2cann_label_image")), filename);
		gtk_image_set_from_file(GTK_IMAGE(lookup_widget(_2CannApp, "image1")), filename);

		gdkPixbuf = gtk_image_get_pixbuf(GTK_IMAGE(lookup_widget(_2CannApp, "image1")));

		n_channels = gdk_pixbuf_get_n_channels (gdkPixbuf);

		g_assert (gdk_pixbuf_get_colorspace (gdkPixbuf)	== GDK_COLORSPACE_RGB);
		g_assert (gdk_pixbuf_get_bits_per_sample (gdkPixbuf) == 8);

		width = gdk_pixbuf_get_width (gdkPixbuf);
		height = gdk_pixbuf_get_height (gdkPixbuf);

		/*g_assert ((x >= 0) && (x < width));
		 g_assert ((y >= 0) && (y < height));*/

		rowstride = gdk_pixbuf_get_rowstride (gdkPixbuf);
		pixels = gdk_pixbuf_get_pixels (gdkPixbuf);

		image = buildImageMatrix(height, width);

		for (i = 0; i < height; i++) {
			for (j = 0; j < width; j++) {
				p = pixels + i * rowstride + j * n_channels;
				image->Matrix[i][j] = p[0];
			}
		}

		imageIsSelected = TRUE;
		imageSelected = image;
		strcpy(imageFilename, filename);

		g_free (filename);
	}

	gtk_widget_destroy (fileChooserDialog);
}

gboolean on_fileChooserDialog_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
	gtk_widget_destroy(fileChooserDialog);
	fileChooserDialog = NULL;
	return FALSE;
}

void on_button1_clicked(GtkButton *button, gpointer user_data) {
	gtk_widget_destroy(fileChooserDialog);
	fileChooserDialog = NULL;
}

void on_button2_clicked(GtkButton *button, gpointer user_data) {

}

void on_erode_activate(GtkMenuItem *menuitem, gpointer user_data) {
}

void on_dilate_activate(GtkMenuItem *menuitem, gpointer user_data) {
}

void on_erode_square_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_QUADRADO3X3;
	mathMorphOP = (char*)malloc(sizeof("erode"));
	mathMorphOP = "erode";
}

void on_erode_cross_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_CRUZ3X3;
	mathMorphOP = (char*)malloc(sizeof("erode"));
	mathMorphOP = "erode";
}

void on_erode_horizontal_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_HORIZONTAL3X3;
	mathMorphOP = (char*)malloc(sizeof("erode"));
	mathMorphOP = "erode";
}

void on_erode_vertical_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_VERTICAL3X3;
	mathMorphOP = (char*)malloc(sizeof("erode"));
	mathMorphOP = "erode";
}

void on_erode_secondary_diagonal_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_DIAGONALSEC3X3;
	mathMorphOP = (char*)malloc(sizeof("erode"));
	mathMorphOP = "erode";
}

void on_erode_main_diagonal_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_DIAGONALPRI3X3;
	mathMorphOP = (char*)malloc(sizeof("erode"));
	mathMorphOP = "erode";
}

void on_dilate_square_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_QUADRADO3X3;
	mathMorphOP = (char*)malloc(sizeof("dilate"));
	mathMorphOP = "dilate";
}

void on_dilate_cross_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_CRUZ3X3;
	mathMorphOP = (char*)malloc(sizeof("dilate"));
	mathMorphOP = "dilate";
}

void on_dilate_horizontal_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_HORIZONTAL3X3;
	mathMorphOP = (char*)malloc(sizeof("dilate"));
	mathMorphOP = "dilate";
}

void on_dilate_vertical_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_VERTICAL3X3;
	mathMorphOP = (char*)malloc(sizeof("dilate"));
	mathMorphOP = "dilate";
}

void on_dilate_main_diagonal_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_DIAGONALPRI3X3;
	mathMorphOP = (char*)malloc(sizeof("dilate"));
	mathMorphOP = "dilate";
}

void on_dilate_secondary_diagonal_activate(GtkMenuItem *menuitem, gpointer user_data) {
	selectSourcePathDialog = create_selectSourcePathDialog();
	gtk_widget_show(selectSourcePathDialog);

	gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label1")), imageFilename);
	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_radioButton1")))
			== TRUE) {

	}

	eeType = EE_DIAGONALSEC3X3;
	mathMorphOP = (char*)malloc(sizeof("dilate"));
	mathMorphOP = "dilate";
}

gboolean on_selectSourcePathDialog_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {

	return FALSE;
}

void on_selectSourcePathDialog_cancelButton_activate(GtkButton *button, gpointer user_data) {

}

void on_selectSourcePathDialog_applyButton_clicked(GtkButton *button, gpointer user_data) {
	struct direct **files;
	int filefilter();
	int i, j, k, numberOfFiles, n_channels, width, height, rowstride;
	guchar *pixels, *p;
	Image *image;
	pixel **Matrix;
	EE ee;
	char *filenameRet = NULL, *filename = NULL, *pathResult = NULL;
	GdkPixbuf *gdkPixbuf, *gdkPixbufRet;

	numberOfFiles = scandir(selectSourcePath, &files, filefilter, alphasort);

	if (numberOfFiles <= 0) {
		printf("No files in this directoryn");
		exit(1);
	}

	pathResult = (char*)malloc(sizeof(selectSourcePath) + sizeof("/result/"));
	sprintf(pathResult, "%s/result/", selectSourcePath);
	mkdir(pathResult, 0755);
	
	for (i = 1; i < (numberOfFiles + 1); ++i) {
		filename = (char*)malloc((sizeof(selectSourcePath) + sizeof("/") + sizeof(files[i-1]->d_name)));
		sprintf(filename, "%s/%s", selectSourcePath, files[i-1]->d_name);
		gdkPixbuf = gdk_pixbuf_new_from_file(filename, NULL);
		
		n_channels = gdk_pixbuf_get_n_channels (gdkPixbuf);

		g_assert (gdk_pixbuf_get_colorspace (gdkPixbuf)	== GDK_COLORSPACE_RGB);

		width = gdk_pixbuf_get_width (gdkPixbuf);
		height = gdk_pixbuf_get_height (gdkPixbuf);

		rowstride = gdk_pixbuf_get_rowstride (gdkPixbuf);
		pixels = gdk_pixbuf_get_pixels (gdkPixbuf);

		image = buildImageMatrix(height, width);

		for (j = 0; j < height; j++) {
			for (k = 0; k < width; k++) {
				p = pixels + j * rowstride + k * n_channels;
				image->Matrix[j][k] = p[0];
			}
		}
		
		setMatrix(&ee, eeType);
		
		Matrix = (pixel**)malloc(getImageHeight(image) * sizeof(pixel*));
		for (j = 0; j < getImageHeight(image); j++) {
			Matrix[j] = (pixel*)malloc(getImageWidth(image)	* sizeof(pixel));
		}
		
		if (strcmp(mathMorphOP, "erode")) {
			Matrix = erode(image->Matrix, &ee, getImageHeight(image), getImageWidth(image), 3, 3);
		} else if (strcmp(mathMorphOP, "dilate")){
			Matrix = dilate(image->Matrix, &ee, getImageHeight(image), getImageWidth(image), 3, 3);
		} else {
			printf("É necessário escolher uma operação\n");
			exit(1);
		}
		
		for (j = 0; j < height; j++) {
			for (k = 0; k < width; k++) {
				p = pixels + i * rowstride + j * n_channels;
				p[0] = p[1] = p[2] = Matrix[j][k];
			}
		}
		gdkPixbufRet = gdk_pixbuf_new(gdk_pixbuf_get_colorspace(gdkPixbuf), gdk_pixbuf_get_has_alpha(gdkPixbuf), 8, gdk_pixbuf_get_width(gdkPixbuf), gdk_pixbuf_get_height(gdkPixbuf));
				
		for (j = 0; j < height; j++) {
			for (k = 0; k < width; k++) {
				p = gdk_pixbuf_get_pixels(gdkPixbufRet) + j * gdk_pixbuf_get_rowstride(gdkPixbufRet) + k * gdk_pixbuf_get_n_channels(gdkPixbufRet);
				p[0] = p[1] = p[2] = (guchar) Matrix[j][k];
			}
		}
		
		free(Matrix);
		filenameRet = (char*)malloc(sizeof(pathResult) + sizeof(mathMorphOP) + sizeof("_") + sizeof(files[i-1]->d_name));
		sprintf(filenameRet, "%s%s_%s", pathResult, mathMorphOP, files[i-1]->d_name);
		//gdk_pixbuf_savev(gdkPixbuf, filenameRet, "bmp", NULL, NULL, NULL);
		gdk_pixbuf_savev(gdkPixbufRet, filenameRet, "bmp", NULL, NULL, NULL);
		
	}
	
	printf("blz\n");
	
	gtk_widget_destroy(selectSourcePathDialog);
}

void on_selectSourcePathDialog_radioButton1_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
	gtk_widget_hide(GTK_WIDGET(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_openbutton")));
}

void on_selectSourcePathDialog_radiobutton2_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
	gtk_widget_show(GTK_WIDGET(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_openbutton")));
}

void set2CannApp(GtkWidget *w) {
	_2CannApp = w;
}

void setSelectSourcePathDialog(GtkWidget *w) {
	selectSourcePathDialog = w;
}

void on_selectSourcePathDialog_openbutton_clicked(GtkButton *button, gpointer user_data) {
	char *extension = (char*)malloc(sizeof("*.") + sizeof(IMAGE_EXTENSION));
	sprintf(extension, "*.%s", IMAGE_EXTENSION);
	
	fileChooserDialog = gtk_file_chooser_dialog_new(_("Select source path of images"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
	gtk_widget_show(fileChooserDialog);
	
	filter = gtk_file_filter_new();
	gtk_file_filter_set_name (filter, "pixmap");
	gtk_file_filter_add_pattern (filter, extension);
	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooserDialog), filter);

	if (gtk_dialog_run (GTK_DIALOG (fileChooserDialog))	== GTK_RESPONSE_ACCEPT) {
		selectSourcePath = (char*)malloc(sizeof(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (fileChooserDialog))));
		selectSourcePath = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooserDialog));

		gtk_label_set_text(GTK_LABEL(lookup_widget(selectSourcePathDialog, "selectSourcePathDialog_label2")), selectSourcePath);
	}
	gtk_widget_destroy (fileChooserDialog);
}

int filefilter(struct direct *entry) {
	char *ptr, *extension;

	extension = (char*)malloc(sizeof(".") + sizeof(IMAGE_EXTENSION));
	sprintf(extension, ".%s", IMAGE_EXTENSION);

	if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
		return (FALSE);
	}

	ptr = rindex(entry->d_name, '.');
	if ((ptr != NULL)&& (strcmp(ptr, extension) == 0)) {
		return (TRUE);
	} else {
		return (FALSE);
	}
}
